﻿//Copyright © 2012  Daniel Lopez

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace NASM_Develop_IDE
{
    public partial class LinkerDialog : Form
    {
        private  delegate bool ComparisonPair<T, T2>(T t, T2 t2);
        private Solution solution;
        private List<string> objectPaths;
        private StringBuilder output;
        public LinkerDialog(Solution solution)
        {
            output = new StringBuilder();
            if (solution == null) throw new ArgumentNullException("Solution is null. Something went clearly wrong.");
            this.solution = solution;
            InitializeComponent();
            TextBoxHighlighter.Highlight(outputName, "Enter Output Name (Extension Optional)");
            TextBoxHighlighter.Highlight(extraParameters, "Enter Additional GCC Command Line Arguments (Optional)");
            DirectoryInfo binInfo = new DirectoryInfo(solution.AbsolutePathOfBinFolder);
            List<FileInfo> objectFileInfos = binInfo.GetFiles("*.obj").ToList();
            objectPaths = new List<string>(objectFileInfos.ConvertAll<string>((FileInfo info) => (info.Name)));
            linkerOrder.Items.AddRange(objectPaths.ToArray());
        }

        private void LinkerDialog_KeyUp(object sender, KeyEventArgs e)
        {

        }

        private void linkerOrder_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
            {
                if (linkerOrder.SelectedIndex > -1)
                {
                    if (linkerOrder.SelectedIndex > 0)
                    {
                        linkerOrder.SelectedIndex -= 1;
                    }
                    else
                    {
                        linkerOrder.SelectedIndex += 1;
                    }
                }
            }
            else if (e.KeyCode == Keys.F1)
            {
                if (linkerOrder.SelectedIndex > -1)
                {
                    if (linkerOrder.SelectedIndex < (linkerOrder.Items.Count - 1))
                    {
                        linkerOrder.SelectedIndex += 1;
                    }
                    else
                    {
                        linkerOrder.SelectedIndex -= 1;
                    }
                }
            }
            else if (e.KeyCode == Keys.Delete)
            {
                if (linkerOrder.SelectedIndex >= 0 && linkerOrder.SelectedIndex < linkerOrder.Items.Count)
                {
                    linkerOrder.Items.RemoveAt(linkerOrder.SelectedIndex);
                }
            }
        }

        private void linkButton_Click(object sender, EventArgs e)
        {
            if (!outputName.Text.EndsWith(".exe"))
            {
                outputName.Text += ".exe";
            }
            StringBuilder arguments = new StringBuilder();
            List<string> objects = new List<string>();
            foreach(string obj in linkerOrder.Items)
            {
                objects.Add(obj);
            }
            for (int index = 0; index < objects.Count; index++)
            {
                objects[index] = solution.AbsolutePathOfBinFolder + "\\" + objects[index];
            }
            objects.ForEach(delegate(string obj)
            {
                arguments.Append("\"" + obj + "\" ");
            });
            if (outputName.Text != "")
            {
                arguments.Append(" -o\"" + solution.AbsolutePathOfBinFolder + "\\" + outputName.Text + "\"");
            }
            else
            {
                arguments.Append(" -o\"" +  solution.AbsolutePathOfBinFolder + "\\default.exe\"");
            }
            if (extraParameters.Text != "")
            {
                arguments.Append(" " + extraParameters.Text);
            }
            StringBuilder linkerOutput;
            bool successfulLink = NASMBuilder.Link(arguments.ToString(), out linkerOutput);
            if (successfulLink)
            {
                
                if (linkerOutput != null)
                    output = linkerOutput;
            }
            this.Close();
        }
        public string OutputName
        {
            get
            {
                if (outputName.Text != string.Empty)
                {
                    return outputName.Text;
                }
                else
                {
                    return "default.exe";
                }
            }
        }
        public string LinkerOutput
        {
            get
            {
                if (output.ToString() == string.Empty)
                {
                    return "No Linker Output! Please check if a problem occured In The 'bin' Folder!";
                }
                else
                {
                    return output.ToString();
                }
            }
        }
        private void linkCancel_Click(object sender, EventArgs e)
        {

            this.Close();
        }
    }
}
